from tkinter import *
# 导入ttk
from tkinter import ttk
from tkinter import messagebox as msgbox
from tkinter import filedialog
from collections import OrderedDict
 
def on_new():
    text.delete(1.0,END)
 
def on_open():
    localfile = filedialog.askopenfile(title='打开单个文件',
                filetypes=[("文本文件","*.txt")],# 只处理的文件类型
                initialdir='D:/')
    if(localfile):
        text.delete(1.0,END)
        with open(localfile.name,'r',encoding='utf-8') as f:
            txt = f.readlines()
        text.insert(END,txt)
    else:
        msgbox.showinfo(message=('读取文件异常'))
 
def on_save():
    localfile = filedialog.asksaveasfile(title='保存文件',
                             filetypes=[("文本文件", "*.txt")],  # 只处理的文件类型
                             initialdir='D:/')
    if(localfile):
        txt = text.get(1.0,END)
        print(txt)
        with open(localfile.name,'w',encoding='utf-8') as f:
            f.write(txt)
    else:
        msgbox.showinfo(message=('读取文件异常'))
 
def on_exit():
    root.destroy()
 
root =Tk()
root.title("菜单测试")
root.geometry('400x200')
 
text =Text(root, height=12, width=60,
            foreground='darkgray',
            font=('微软雅黑',12),
            spacing2=8,# 设置行间距
            spacing3=12)# 设置段间距
text.pack(fill=BOTH,expand=Y)
st ='Tkinter 为菜单提供了 Menu 类，该类既可代表菜单条，也可代表菜单，还可代表上下文菜单（右键菜单）。简单来说，Menu 类就可以搞定所有菜单相关内容。\n'
text.insert(END, st)
scroll =Scrollbar(text, command=text.yview)
scroll.pack(side=RIGHT, fill=Y)
# 设置text2的纵向滚动影响scroll滚动条
text.configure(yscrollcommand=scroll.set)
text.configure(state=NORMAL)
 
menubar =Menu(root)
root['menu']= menubar
file_menu =Menu(menubar, tearoff=0)
menubar.add_cascade(label='文件', menu=file_menu)
lang_menu =Menu(menubar, tearoff=0)
menubar.add_cascade(label='格式', menu=lang_menu)
file_menu.add_command(label="新建", command=on_new)
file_menu.add_command(label="打开", command=on_open)
file_menu.add_command(label="保存", command=on_save)
file_menu.add_separator()
file_menu.add_command(label="退出", command=on_exit)
lang_menu.add_command(label="字体", command = None)
lang_menu.add_command(label="颜色", command = None)
 
def popup(event):
    # 在指定位置显示菜单
    popup_menu.post(event.x_root, event.y_root)
 
def choose(x):
    # 如果用户选择修改字体大小的子菜单项
    if x in my_items[0].keys():
        # 改变字体大小
        text['font'] = ('微软雅黑', my_items[0][x])
    # 如果用户选择修改颜色的子菜单项
    if x in my_items[1].keys():
        # 改变颜色
        text['foreground'] = my_items[1][x]
 
def handlerAdaptor(fun, **kwds):
    return lambda fun=fun, kwds=kwds: fun(**kwds)
 
text.bind('<Button-3>', popup)
popup_menu = Menu(text, tearoff=0)
my_items = (OrderedDict([('超大', 16), ('大', 14), ('中', 12),
                              ('小', 10), ('超小', 8)]),
                 OrderedDict([('红色', 'red'), ('绿色', 'green'), ('蓝色', 'blue')]))
i = 0
for k in ['字体大小', '颜色']:
    m = Menu(popup_menu, tearoff=0)
    popup_menu.add_cascade(label=k, menu=m)
    # 遍历OrderedDict的key（默认就是遍历key）
    for im in my_items[i]:
        m.add_command(label=im, command=handlerAdaptor(choose, x=im))
    i += 1
 
root.mainloop()